const { pool } = require('../config/database');
const { formatDateTime } = require('../utils/dateFormatter');
const logger = require('../utils/logger');

class MenuModel {
  // 创建菜单
  async create(menuData) {
    try {
      const [result] = await pool.execute(
        `INSERT INTO menus 
        (parent_id, name, menu_type, path, component, icon, sort, status) 
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          menuData.parent_id || 0,
          menuData.name,
          menuData.menu_type,
          menuData.path || null,
          menuData.component || null,
          menuData.icon || null,
          menuData.sort || 0,
          menuData.status !== undefined ? menuData.status : 1
        ]
      );
      return result.insertId;
    } catch (error) {
      logger.error('创建菜单数据库操作失败:', {
        error: error.message,
        code: error.code,
        stack: error.stack,
        menuData
      });
      
      throw new Error('创建菜单失败: ' + error.message);
    }
  }

  // 通过ID获取菜单
  async findById(id) {
    try {
      const [rows] = await pool.execute(
        `SELECT id, parent_id, name, menu_type, path, component, icon, sort, status, 
        created_at, updated_at 
        FROM menus 
        WHERE id = ? AND is_deleted = 0`,
        [id]
      );
      return rows[0] ? this.formatMenuData(rows[0]) : null;
    } catch (error) {
      logger.error('查询菜单失败:', error);
      throw error;
    }
  }

  // 获取所有菜单
  async findAll() {
    try {
      const [rows] = await pool.execute(
        `SELECT id, parent_id, name, menu_type, path, component, icon, sort, status, 
        created_at, updated_at 
        FROM menus 
        WHERE is_deleted = 0 
        ORDER BY sort ASC, id ASC`
      );
      return rows.map(row => this.formatMenuData(row));
    } catch (error) {
      logger.error('查询所有菜单失败:', error);
      throw error;
    }
  }

  // 更新菜单
  async update(id, menuData) {
    try {
      const updateFields = [];
      const params = [];

      // 动态构建更新字段
      if (menuData.name !== undefined) {
        updateFields.push('name = ?');
        params.push(menuData.name);
      }
      
      if (menuData.menu_type !== undefined) {
        updateFields.push('menu_type = ?');
        params.push(menuData.menu_type);
        
        // 如果菜单类型为5(权限控制)，则清空path、component和icon
        if (menuData.menu_type === 5) {
          updateFields.push('path = NULL');
          updateFields.push('component = NULL');
          updateFields.push('icon = NULL');
        }
      } else {
        // 如果没有修改菜单类型，则正常更新其他字段
        if (menuData.path !== undefined) {
          updateFields.push('path = ?');
          params.push(menuData.path || null);
        }
        
        if (menuData.component !== undefined) {
          updateFields.push('component = ?');
          params.push(menuData.component || null);
        }
        
        if (menuData.icon !== undefined) {
          updateFields.push('icon = ?');
          params.push(menuData.icon || null);
        }
      }
      
      if (menuData.sort !== undefined) {
        updateFields.push('sort = ?');
        params.push(menuData.sort);
      }
      
      if (menuData.status !== undefined) {
        updateFields.push('status = ?');
        params.push(menuData.status);
      }

      // 如果没有要更新的字段，直接返回
      if (updateFields.length === 0) {
        return false;
      }

      // 添加ID参数
      params.push(id);

      const [result] = await pool.execute(
        `UPDATE menus SET ${updateFields.join(', ')} WHERE id = ? AND is_deleted = 0`,
        params
      );

      return result.affectedRows > 0;
    } catch (error) {
      logger.error('更新菜单失败:', error);
      throw error;
    }
  }

  // 软删除菜单
  async softDelete(id) {
    try {
      // 开启事务
      const connection = await pool.getConnection();
      await connection.beginTransaction();

      try {
        // 1. 获取所有子菜单ID
        const childIds = await this.getAllChildIds(id, connection);
        
        // 2. 删除当前菜单
        const [result] = await connection.execute(
          'UPDATE menus SET is_deleted = 1 WHERE id = ?',
          [id]
        );
        
        // 3. 删除所有子菜单
        if (childIds.length > 0) {
          await connection.execute(
            `UPDATE menus SET is_deleted = 1 WHERE id IN (${childIds.join(',')})`,
            []
          );
        }
        
        // 4. 删除角色菜单关联记录
        const allIds = [id, ...childIds];
        await connection.execute(
          `DELETE FROM role_menus WHERE menu_id IN (${allIds.join(',')})`,
          []
        );

        // 提交事务
        await connection.commit();
        
        return result.affectedRows > 0;
      } catch (error) {
        // 回滚事务
        await connection.rollback();
        throw error;
      } finally {
        // 释放连接
        connection.release();
      }
    } catch (error) {
      logger.error('删除菜单失败:', error);
      throw error;
    }
  }

  // 递归获取所有子菜单ID
  async getAllChildIds(parentId, connection) {
    const [rows] = await connection.execute(
      'SELECT id FROM menus WHERE parent_id = ? AND is_deleted = 0',
      [parentId]
    );
    
    let ids = rows.map(row => row.id);
    
    // 递归获取子菜单的子菜单
    for (const id of ids) {
      const childIds = await this.getAllChildIds(id, connection);
      ids = [...ids, ...childIds];
    }
    
    return ids;
  }

  // 获取菜单树
  async getMenuTree() {
    try {
      const allMenus = await this.findAll();
      
      // 构建菜单树
      const menuMap = {};
      const rootMenus = [];
      
      // 第一步：将所有菜单放入map
      allMenus.forEach(menu => {
        menu.children = [];
        menuMap[menu.id] = menu;
      });
      
      // 第二步：构建树形结构
      allMenus.forEach(menu => {
        if (menu.parent_id === 0) {
          rootMenus.push(menu);
        } else {
          const parent = menuMap[menu.parent_id];
          if (parent) {
            parent.children.push(menu);
          }
        }
      });
      
      // 第三步：排序
      const sortMenus = (menus) => {
        menus.sort((a, b) => a.sort - b.sort);
        menus.forEach(menu => {
          if (menu.children && menu.children.length > 0) {
            sortMenus(menu.children);
          }
        });
      };
      
      sortMenus(rootMenus);
      
      return rootMenus;
    } catch (error) {
      logger.error('获取菜单树失败:', error);
      throw error;
    }
  }

  // 获取用户菜单
  async getUserMenus(roleId) {
    try {
      const [rows] = await pool.execute(
        `SELECT m.id, m.parent_id, m.name, m.menu_type, m.path, m.component, m.icon, m.sort
         FROM menus m
         JOIN role_menus rm ON m.id = rm.menu_id
         WHERE rm.role_id = ? AND m.status = 1 AND m.is_deleted = 0
         ORDER BY m.menu_type, m.sort ASC, m.id ASC`,
        [roleId]
      );
      
      const menus = rows.map(row => this.formatMenuData(row));
      
      // 构建菜单树
      const menuMap = {};
      const rootMenus = [];
      
      // 第一步：将所有菜单放入map
      menus.forEach(menu => {
        menu.children = [];
        menuMap[menu.id] = menu;
      });
      
      // 第二步：构建树形结构
      menus.forEach(menu => {
        if (menu.parent_id === 0) {
          rootMenus.push(menu);
        } else {
          const parent = menuMap[menu.parent_id];
          if (parent) {
            parent.children.push(menu);
          }
        }
      });
      
      return rootMenus;
    } catch (error) {
      logger.error('获取用户菜单失败:', error);
      throw error;
    }
  }

  // 验证菜单类型和父级关系
  async validateMenuTypeAndParent(menuData) {
    try {
      const { menu_type, parent_id } = menuData;
      
      // 一级菜单的parent_id必须为0
      if (menu_type === 1 && parent_id !== 0) {
        return { valid: false, message: '一级菜单的父级ID必须为0' };
      }
      
      // 二级菜单的parent_id必须是一级菜单ID
      if (menu_type === 2 && parent_id !== 0) {
        const [rows] = await pool.execute(
          'SELECT id, menu_type FROM menus WHERE id = ? AND is_deleted = 0',
          [parent_id]
        );
        
        if (rows.length === 0) {
          return { valid: false, message: '父级菜单不存在' };
        }
        
        if (rows[0].menu_type !== 1) {
          return { valid: false, message: '二级菜单的父级必须是一级菜单' };
        }
      }
      
      // 三级菜单的parent_id必须是二级菜单ID
      if (menu_type === 3 && parent_id !== 0) {
        const [rows] = await pool.execute(
          'SELECT id, menu_type FROM menus WHERE id = ? AND is_deleted = 0',
          [parent_id]
        );
        
        if (rows.length === 0) {
          return { valid: false, message: '父级菜单不存在' };
        }
        
        if (rows[0].menu_type !== 2) {
          return { valid: false, message: '三级菜单的父级必须是二级菜单' };
        }
      }
      
      // 组件路由的parent_id必须是一级、二级或三级菜单ID
      if (menu_type === 4 && parent_id !== 0) {
        const [rows] = await pool.execute(
          'SELECT id, menu_type FROM menus WHERE id = ? AND is_deleted = 0',
          [parent_id]
        );
        
        if (rows.length === 0) {
          return { valid: false, message: '父级菜单不存在' };
        }
        
        if (![1, 2, 3].includes(rows[0].menu_type)) {
          return { valid: false, message: '组件路由的父级必须是一级、二级或三级菜单' };
        }
      }
      
      return { valid: true };
    } catch (error) {
      logger.error('验证菜单类型和父级关系失败:', error);
      throw error;
    }
  }

  // 格式化菜单数据
  formatMenuData(menu) {
    return {
      id: menu.id,
      parent_id: menu.parent_id,
      name: menu.name,
      menu_type: menu.menu_type,
      path: menu.path,
      component: menu.component,
      icon: menu.icon,
      sort: menu.sort,
      status: menu.status,
      created_at: menu.created_at ? formatDateTime(menu.created_at) : null,
      updated_at: menu.updated_at ? formatDateTime(menu.updated_at) : null
    };
  }
}

module.exports = new MenuModel(); 